#include "CApp.h"

#include "CScore.h"
#include <iostream>

CScore CScore::Score;

#include <stdio.h>
#include <stdlib.h>
#include <cstring>

bool CScore::OnLoad(char* link) {
    Data[0].clear();
    Data[1].clear();
    Data[2].clear();

    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(link);
    if (!result)
        return false;

    pugi::xml_node players = doc.child("Easy").child("Players");
    for (pugi::xml_node player = players.child("Player"); player; player = player.next_sibling("Player")) {
        Man buf;
        buf.Name = new char;
        strcpy(buf.Name, player.attribute("name").value());
        buf.Score = atoi((char*)player.attribute("score").value());
        Data[0].push_back(buf);
        //std::cout << Data[Data.size() - 1].Name << std::endl;
    }

    players = doc.child("Medium").child("Players");
    for (pugi::xml_node player = players.child("Player"); player; player = player.next_sibling("Player")) {
        Man buf;
        buf.Name = new char;
        strcpy(buf.Name, player.attribute("name").value());
        buf.Score = atoi((char*)player.attribute("score").value());
        Data[1].push_back(buf);
        //std::cout << Data[Data.size() - 1].Name << std::endl;
    }

    players = doc.child("Hard").child("Players");
    for (pugi::xml_node player = players.child("Player"); player; player = player.next_sibling("Player")) {
        Man buf;
        buf.Name = new char;
        strcpy(buf.Name, player.attribute("name").value());
        buf.Score = atoi((char*)player.attribute("score").value());
        Data[2].push_back(buf);
        //std::cout << Data[Data.size() - 1].Name << std::endl;
    }

    Length.Start = 0;
    if (int(Data[Level].size()) <= 9)
        Length.End = int(Data[Level].size());
    else
        Length.End = 9;

    Anim = false;
    Surf_table = CSurface::OnLoad("content/image/table.jpg");

    return true;
}

bool CScore::AddScore(char* Name, int X, char* link) {
    Man buf;
    buf.Name = Name; buf.Score = X;

    for (int i = 0; i < int(Data[Level].size()); i++)
        if (!strcmp(Data[Level][i].Name, buf.Name)) {
                return false;
            }

    Data[Level].push_back(buf);
    for (int i = 0; i < int(Data[Level].size()); i++)
        for (int j = 0; j < i; j++)
            if (Data[Level][i].Score > Data[Level][j].Score) {
                Man tmp = Data[Level][i];
                Data[Level][i] = Data[Level][j];
                Data[Level][j] = tmp;
            }

    for (int i = 0; i < int(Data[Level].size()); i++)
        if (!strcmp(Name, Data[Level][i].Name)) {
            Target = i;
            break;
        }

    pugi::xml_document doc;
    pugi::xml_node node = doc.append_child("Easy");
    doc.child("Easy").append_child("Players");
    for (int i = 0; i < int(Data[0].size()); i++) {
        pugi::xml_node param = doc.child("Easy").child("Players").append_child("Player");
        param.append_attribute("name") = Data[0][i].Name;
        param.append_attribute("score") = Data[0][i].Score;
    }
    node = doc.append_child("Medium");
    doc.child("Medium").append_child("Players");
    for (int i = 0; i < int(Data[1].size()); i++) {
        pugi::xml_node param = doc.child("Medium").child("Players").append_child("Player");
        param.append_attribute("name") = Data[1][i].Name;
        param.append_attribute("score") = Data[1][i].Score;
    }
    node = doc.append_child("Hard");
    doc.child("Hard").append_child("Players");
    for (int i = 0; i < int(Data[2].size()); i++) {
        pugi::xml_node param = doc.child("Hard").child("Players").append_child("Player");
        param.append_attribute("name") = Data[2][i].Name;
        param.append_attribute("score") = Data[2][i].Score;
    }
    doc.save_file(link);
    return true;
}

bool CScore::OnDraw(SDL_Surface* Surf_Display, TTF_Font* Font) {
    CSurface::OnDraw(Surf_Display, Surf_table, 42, 142);
    for (int i = Length.Start; i < Length.End; i++) {
        CFont::OnDraw(Font, 1, i + 1, Surf_Display, 50, 180 + (i - Length.Start) * 30);
        CFont::OnDraw(Font, 1, "|", Surf_Display, 76, 180 + (i - Length.Start) * 30);
        if (i == Target)
            CFont::OnDraw(Font, 2, Data[Level][i].Name, Surf_Display, 85, 180 + (i - Length.Start) * 30);
        else
            CFont::OnDraw(Font, 1, Data[Level][i].Name, Surf_Display, 85, 180 + (i - Length.Start) * 30);

        CFont::OnDraw(Font, 1, Data[Level][i].Score, Surf_Display, Surf_Display->w - 240, 180 + (i - Length.Start) * 30);
    }

    return true;
}

void CScore::ScrollUp() {
    if (Length.Start - 1 >= 0)
    { Length.Start--; Length.End--; }
}

void CScore::ScrollDown() {
    if (Length.End + 1 <= int(Data[Level].size()))
    { Length.Start++; Length.End++; }
}

void CScore::NextLevel() {
    Target = -1;
    bLevel = Level + 1;
    if (bLevel > 2)
        bLevel = 2;
    if (bLevel != Level)
        Anim = true;
    bLength.Start = 0;
    if (int(Data[bLevel].size()) <= 9)
        bLength.End = int(Data[bLevel].size());
    else
        bLength.End = 9;
    X = 50;
    if (bLevel > Level)
        bX = X + 640;
    else
        bX = X - 640;
    vx = 10;
}
void CScore::ExLevel() {
    Target = -1;
    bLevel = Level - 1;
    if (bLevel < 0)
        bLevel = 0;
    if (bLevel != Level)
        Anim = true;
    if (int(Data[bLevel].size()) <= 9)
        bLength.End = int(Data[bLevel].size());
    else
        bLength.End = 9;
    X = 50;
    if (bLevel > Level)
        bX = X + 640;
    else
        bX = X - 640;
    vx = 6;
}

void CScore::Animate(SDL_Surface* Surf_Display, TTF_Font* Font) {
    if (bLevel < Level) {
        if (bX > 50) {
            vx = 2;
            bX -= vx;
            if (bX < 50)
                bX = 50;
        } else {
            X += vx;
            bX += vx;
        }
    }
    if (bLevel > Level) {
        if (bX < 50) {
            vx = 2;
            bX += vx;
            if (bX > 50)
                bX = 50;
        } else {
            X -= vx;
            bX -= vx;
        }
    }
    vx++;

    if (bX != 50) {
        CSurface::OnDraw(Surf_Display, Surf_table, X - 8, 142);
        for (int i = Length.Start; i < Length.End; i++) {
            CFont::OnDraw(Font, 1, i + 1, Surf_Display, X, 180 + (i - Length.Start) * 30);
            CFont::OnDraw(Font, 1, "|", Surf_Display, X + 26, 180 + (i - Length.Start) * 30);
            if (i == Target)
                CFont::OnDraw(Font, 2, Data[Level][i].Name, Surf_Display, X + 35, 180 + (i - Length.Start) * 30);
            else
                CFont::OnDraw(Font, 1, Data[Level][i].Name, Surf_Display, X + 35, 180 + (i - Length.Start) * 30);

            CFont::OnDraw(Font, 1, Data[Level][i].Score, Surf_Display, X + 350, 180 + (i - Length.Start) * 30);
        }

        CSurface::OnDraw(Surf_Display, Surf_table, bX - 8, 142);
        for (int i = bLength.Start; i < bLength.End; i++) {
            CFont::OnDraw(Font, 1, i + 1, Surf_Display, bX, 180 + (i - bLength.Start) * 30);
            CFont::OnDraw(Font, 1, "|", Surf_Display, bX + 26, 180 + (i - bLength.Start) * 30);
            if (i == Target)
                CFont::OnDraw(Font, 2, Data[bLevel][i].Name, Surf_Display, bX + 35, 180 + (i - bLength.Start) * 30);
            else
                CFont::OnDraw(Font, 1, Data[bLevel][i].Name, Surf_Display, bX + 35, 180 + (i - bLength.Start) * 30);

            CFont::OnDraw(Font, 1, Data[bLevel][i].Score, Surf_Display, bX + 350, 180 + (i - bLength.Start) * 30);
        }
    } else {
        Anim = false;
        Level = bLevel;
        Length = bLength;
        OnDraw(Surf_Display, Font);
    }
}
